#ifndef _DEMOTEMP_H
#define _DEMOTEMP_H

#ifdef PALLOCATOR
#include "Pallocator.h"
#endif
#include <pthread.h>
#include <unistd.h>
#include <cstdlib>


#ifdef PALLOCATOR
#define mymalloc palloc
#define myfree pafree
#else
#define mymalloc malloc
#define myfree free
#endif

typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
typedef unsigned long long u64;

#define MIN(a,b) ((a)<(b)?(a):(b))
#define MAX(a,b) ((a)>(b)?(a):(b))

static const int MB = 1048576;
static const int KB = 1024;

#ifndef PATH_MAX
static const int PATH_MAX = 256;
#endif

struct Item;

typedef int (*FuncCompare)(Item *, Item *);

class SpinLock
{
public:
    int Init() { return pthread_spin_init(&lock, 0);}
    int Destroy() { return pthread_spin_destroy(&lock);}
    int Lock() { return pthread_spin_lock(&lock);}
    int UnLock() { return pthread_spin_unlock(&lock);}

    int TryLock() 
    { 
        if (!pthread_spin_trylock(&lock))
        {
            return 0;
        }
        else
        {
            return -1;
        }
    }
private:
    pthread_spinlock_t lock;
};

class RWLock
{
public:
    int Init() { return pthread_rwlock_init(&lock, NULL);}
    int Destroy() { return pthread_rwlock_destroy(&lock);}
    int WLock() { return pthread_rwlock_wrlock(&lock);}
    int RLock() { return pthread_rwlock_rdlock(&lock);}

    int TryWLock()
    {
        if (!pthread_rwlock_trywrlock(&lock))
        {
            return 0;
        }
        else
        {
            return -1;
        }
    }

    int TryRLock()
    {
        if (!pthread_rwlock_tryrdlock(&lock))
        {
            return 0;
        }
        else
        {
            return -1;
        }
    }

    int UnLock() { return pthread_rwlock_unlock(&lock);}

private:
    pthread_rwlock_t lock;
};

//
//#define VOIDPP(x) reinterpret_cast<void**>(&x)
//
//class PtrLock
//{
//public:
//    void Init(u32 buckets)
//    {
//        bucket_num = buckets;
//        locks = (SpinLock *)mymalloc(sizeof(SpinLock)*bucket_num);
//        for(u32 i = 0; i < bucket_num; ++i) 
//        {
//            locks[i].Init();
//        }
//    }
//
//    void Destroy()
//    {
//        for(u32 i = 0; i < bucket_num; ++i)
//        {
//            locks[i].Destroy();
//        }
//        myfree(locks);
//    }
//
//    int Lock(void **ptr)
//    {
//        //BKDRHash
//        u32 id = 0;
//
//        for(u32 i = 0; i < sizeof(void*); ++i)
//        {
//            id = id * 131 + reinterpret_cast<u8*>(ptr)[i];
//        }
//        id %= bucket_num;
//        if (locks[id].TryLock() == 0)
//            return id;
//        else
//            return -1;
//    }
//
//    void UnLock(u32 id)
//    {
//        locks[id].UnLock();
//    }
//
//private:
//    u32 bucket_num;
//    SpinLock *locks;
//};
//
//#endif
